# encoding: utf-8
import sys, os, re, rsa
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.Qt import Qt
from datetime import datetime, timedelta
import license, keygen_rc, utils
from base64 import b64encode, b64decode


def key_gen(maccode, product, version='1.0', email='', edate=None, keyfile=None):
    try:
        pub_key, pri_key = license.new_keys(product, nbits=2048)
        if not edate:
            sdate = datetime.now()
            edate = sdate.replace(year=sdate.year+1)

        edate = datetime.utcfromtimestamp(edate.timestamp())
        message = 'maccode:{};product:{};version:{};email:{};expire-date:{};'.format(
            maccode, product, version, email,
            edate.timestamp()).encode()
        
        message += b'<pub_key>' + \
                   utils.aes_enc(license.aes_key[::8].encode(), pub_key.save_pkcs1()) + \
                   b'</pub_key>'

        sig = rsa.sign(message, pri_key, 'SHA-256')
        encdata = b64encode(sig+message)
        kf = keyfile if keyfile else '%s.lic' % (product,)
        with open(kf, 'wb') as fp:
            fp.write(encdata)
        return encdata, pub_key
    except BaseException:
        raise


class MainWindow(QtWidgets.QDialog):
    def __init__(self, parent = None):
        super(MainWindow, self).__init__(parent)
        self.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowCloseButtonHint)
        self.setWindowState(Qt.WindowNoState)
        mainLayout = QtWidgets.QVBoxLayout()
        self.createMessageGroupBox(mainLayout)
        self.buttonBox = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok |
                                                    QtWidgets.QDialogButtonBox.Cancel
                                                    , self)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.button(QtWidgets.QDialogButtonBox.Ok).setText(self.tr('生成'))
        self.buttonBox.button(QtWidgets.QDialogButtonBox.Cancel).setText(self.tr('退出'))
        self.buttonBox.rejected.connect(self.reject)
        self.cwd = os.path.join(os.path.dirname(os.path.abspath(__file__)))

        mainLayout.addWidget(self.buttonBox)
        self.setLayout(mainLayout)
        self.setWindowTitle(self.tr("注册机"))
        self.setWindowIcon(QtGui.QIcon(':/images/app.ico'))
        self.resize(360,280)

    def get_lic_expr_date(self, sdate):
        span = int(self.licspanEdit.text())
        currentIndex = self.spanUnit.currentIndex()
        if currentIndex == 2:
            return sdate.replace(year = sdate.year+span)
        elif currentIndex == 1:
            return sdate.replace(year=sdate.year+int(span/12), month=sdate.month+int(span%12))
        return sdate + timedelta(days=span)

    def accept(self):
        if  self.emailEdit.text() and not self.emailEdit.hasAcceptableInput():
            QtWidgets.QMessageBox.warning(self, self.tr('邮箱校验'), self.tr('邮箱格式错误'), QtWidgets.QMessageBox.Ok)
            return

        edate = self.startdate.dateTime().toPyDateTime()
        key_gen(self.macEdit.text(), self.productEdit.currentText(),
                        self.versionEdit.text(),
                        self.emailEdit.text(),
                        edate, self.licpathEdit.text())
        super(MainWindow, self).accept()

    def reject(self):
        super(MainWindow, self).reject()

    def select_lic_path(self):
        fpath = os.path.join(self.cwd, '%s-%s' %(self.productEdit.currentText(), self.versionEdit.text()))
        fpath, _ = QtWidgets.QFileDialog.getSaveFileName(self, directory=fpath,
                                                         filter=self.tr('license Files (*.lic)'))
        self.licpathEdit.setText(fpath)

    def createMessageGroupBox(self, mlayout):
        macLabel = QtWidgets.QLabel(self.tr("机器码:"))
        self.macEdit = QtWidgets.QLineEdit(license.get_hwid())
  
        productLabel = QtWidgets.QLabel(self.tr("产品名称:"))
        self.productEdit = QtWidgets.QComboBox()
        self.productEdit.addItems(['AlgWeb'])

        versionLabel = QtWidgets.QLabel(self.tr("产品版本:"))
        self.versionEdit = QtWidgets.QLineEdit('1.0')

        emailLabel = QtWidgets.QLabel(self.tr("Email:"))
        self.emailEdit = QtWidgets.QLineEdit(self)
        self.emailEdit.setValidator(QtGui.QRegularExpressionValidator( 
                            QtCore.QRegularExpression(r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9]+\.[A-Za-z]{2,4}'), self))
 

        sdateLabel = QtWidgets.QLabel(self.tr("许可到期时间:"))
        self.startdate = QtWidgets.QDateTimeEdit(
            QtCore.QDateTime(datetime.now()+timedelta(days=180)))
        self.startdate.setDisplayFormat('yyyy-MM-dd HH:mm:ss')


        licpathLabel = QtWidgets.QLabel(self.tr("许可文件路径:"))
        self.licpathEdit = QtWidgets.QLineEdit()
        self.licpathBtn = QtWidgets.QPushButton()
        self.licpathBtn.clicked.connect(self.select_lic_path)

        layout = QtWidgets.QGridLayout()
        layout.addWidget(macLabel, 0, 0)
        layout.addWidget(self.macEdit, 0, 1, 1, 2)

        layout.addWidget(productLabel, 1, 0)
        layout.addWidget(self.productEdit, 1, 1, 1, 2)

        layout.addWidget(versionLabel, 2, 0)
        layout.addWidget(self.versionEdit, 2, 1, 1, 2)

        layout.addWidget(emailLabel, 3, 0)
        layout.addWidget(self.emailEdit, 3, 1, 1, 2)

        layout.addWidget(sdateLabel, 4, 0)
        layout.addWidget(self.startdate, 4, 1, 1, 2)

        layout.addWidget(licpathLabel, 5, 0)
        layout.addWidget(self.licpathEdit, 5, 1)
        layout.addWidget(self.licpathBtn, 5, 2)

        mlayout.addLayout(layout)



def main(args):
    app = QtWidgets.QApplication(args)
    dlg = MainWindow()
    dlg.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main(sys.argv)


